package cn.demoncat.util.mybatis.plus.config;

import cn.demoncat.util.lang.OptionalUtil;
import cn.demoncat.util.lang.constant.StringConstant;
import cn.demoncat.util.lang.entity.MapSs;
import org.apache.commons.collections4.MapUtils;

import java.util.Map;

/**
 * 动态表名持有者
 *
 * 配置：db.dynamic-table=1支持，0不支持（默认）
 *
 * @author 延晓磊
 * @since 2021年09月14日
 */
public class DynamicTableHolder {

    /**
     * 表名映射存储：{静态表名:动态表名后缀}
     */
    private static final ThreadLocal<Map<String, String>> STORE = new ThreadLocal<>();

    /**
     * 添加动态表映射
     *
     * <pre>
     *     场景：操作动态表
     *     使用：添加动态表映射(线程有效) > 执行动态表操作
     *     注意：如果表不存在，在操作时会报错 SQLSyntaxErrorException
     * </pre>
     *
     * @param map {静态表名:动态表名后缀}
     *
     * @author 延晓磊
     * @since 2021年09月14日
     */
    public static void set(Map<String,String> map){
        STORE.set(map);
    }

    /**
     * 添加动态表映射
     *
     * <pre>
     *     场景：操作动态表
     *     使用：添加动态表映射(线程有效) > 执行动态表操作
     *     注意：如果表不存在，在操作时会报错 SQLSyntaxErrorException
     * </pre>
     *
     * @param table     静态表名
     * @param suffix    动态表名后缀
     *
     * @author 延晓磊
     * @since 2021年09月14日
     */
    public static void set(String table, String suffix){
        Map<String, String> map = STORE.get();
        if (map == null) {
            set(MapSs.getInstance(table, suffix));
        }else{
            map.put(table, suffix);
        }
    }

    /**
     * 获取动态表映射
     *
     * @param table 静态表名
     *
     * @return 静态表名 || 静态表名_动态表名后缀
     *
     * @author 延晓磊
     * @since 2021年09月14日
     */
    public static String get(String table){
        Map<String, String> map = STORE.get();
        if (MapUtils.isNotEmpty(map)) {
            return OptionalUtil.get(map.get(table), table, o -> table + StringConstant.UNDER_LINE + o);
        }
        return table;
    }

    /**
     * 清除
     *
     * <pre>
     *     场景：操作动态表后，操作非动态表（同源）
     *     使用：移除动态表映射(线程有效) > 执行非动态表操作
     * </pre>
     *
     * @param table 静态表名
     *
     * @author 延晓磊
     * @since 2021年09月14日
     */
    public static void remove(String table){
        OptionalUtil.consumer(STORE.get(), map -> map.remove(table));
    }

    /**
     * 清除
     *
     * <pre>
     *     场景：操作动态表后，操作非动态表（同源）
     *     使用：移除动态表映射(线程有效) > 执行非动态表操作
     * </pre>
     *
     * @author 延晓磊
     * @since 2021年09月14日
     */
    public static void clear(){
        STORE.remove();
    }

}
